import { useThrottleFn, useDebounceFn } from "@vueuse/core";
import { Ref, ref, unref, watch } from "vue";

interface UseEventParams {
  el: Element | Window ;
  name: string;
  listener: () => void;
  wait?: number;
  isDebounce?: boolean;
  options?: boolean | AddEventListenerOptions;
}

//事件监听hooks
export default function useEvent({
  el,
  name,
  listener,
  wait = 80,
  isDebounce = true,
  options,
}: UseEventParams): { removeFn: () => void } {

    //选择防抖节流
  const eventControl = isDebounce
    ? useDebounceFn(listener, wait)
    : useThrottleFn(listener, wait);
    //判断是否需要防抖节流
  const eventFn = wait ? eventControl : listener;

  const elRef = ref(el) as Ref<Element>;
  //判断是否已添加事件监听
  const isAdd: Ref<boolean> = ref(false);

  //添加事件监听
  function addEventListener(v: Element) {
    isAdd.value = true;
    v.addEventListener(name, eventFn, options);
  }

  //删除事件监听
  function removeEventListener(v: Element) {
    isAdd.value = false;
    v.removeEventListener(name, eventFn, options);
  }

  //watch 先立即执行 随后在el变化时删除监听后再重新监听
  const removeWatch =  watch(elRef, (v, _oldV, cleanUp) => {
    if (v) {
      !unref(isAdd) && addEventListener(v);
      cleanUp(() => {
        unref(isAdd) && removeEventListener(v);
      });
    }
  },{
    immediate:true
  });

  //删除方法 删除监听与watch
  const removeFn = () => {
    removeWatch()
    removeEventListener(elRef.value);
  };

  return {
    removeFn,
  };
}
